package com.socio.behaviors;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheManager;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.memcache.MemcacheService;
import com.socio.utils.PMF;
import com.socio.utils.FieldAccessor.FieldAccessorField;


/**
 * An abstraction of DAO behaviors. Methods for basic CRUD functions to be implemented
 * by subclass and a method for custom query execution. Also includes a convenience persist
 * method.
 * 
 * @author potlow
 *
 */
public abstract class DAOBehavior {
	protected PersistenceManagerFactory pmf;
	protected Cache cache;

    public DAOBehavior() {
        pmf = PMF.getPersistenceManagerFactory();
        try {
        	Map<Object,Boolean> props = new HashMap<Object,Boolean>();
            props.put(MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT, true);
	        cache = CacheManager.getInstance().getCacheFactory().createCache(props);
        } catch (CacheException e) {}
    }

    public abstract boolean create(Object value);
    public abstract boolean delete(Object value);
    public abstract List<Object> execute(String filter, String declareParameters, String ordering, Long[] queryRange,
            Map<String, Object> parameters, List<FieldAccessorField> touchFields);
    public abstract List<Key> getAllKeys();
    public abstract List<Object> read(Object filter, List<FieldAccessorField> touchFields);
    public abstract Object update(Object filter, List<FieldAccessorField> updateFields, 
			List<Object> updatedValues, List<FieldAccessorField> touchFields);


    protected boolean persist(Object object) {
        PersistenceManager pm = pmf.getPersistenceManager();
    	boolean didPersist = false;

        try {
            pm.makePersistent(object);
            didPersist = true;
        } finally {
            pm.close();
        }

        return didPersist;
    }
}
